<template>
  <!-- 环境光 -->
  <div class="ambient-light">
    <div id="scene"></div>
    <div class="color-select">
      <div>
        <span>颜色选择</span>
        <el-color-picker v-model="ambientColor">颜色选择</el-color-picker>
      </div>
    </div>
  </div>
</template>

<script>
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";

let scene; //场景
let camera; //相机
let renderer; //创建渲染器
let controls; //控制器
let ambient; //环境光
export default {
  name: "Scene",
  data() {
    return {
      ambientColor: "#409EFF",
    };
  },
  mounted() {
    this.createScene();
    this.createMesh();
    this.createCubeAndSphere();
    this.createLight();
    this.createCamera();
    this.createRender();
    this.createControls();
    this.render();
  },
  methods: {
    createScene() {
      //创建场景
      scene = new THREE.Scene();
    },
    // 创建网格模型
    createMesh() {
      // 创建一个平面对象PlaneGeometry
      const planeGeometry = new THREE.PlaneGeometry(60, 20, 1, 1);
      // 材质对象
      const planeMaterial = new THREE.MeshLambertMaterial({
        color: 0xffffff,
      });
      const plane = new THREE.Mesh(planeGeometry, planeMaterial);
      plane.receiveShadow = true;

      plane.rotation.x = -0.5 * Math.PI;
      plane.position.set(15, 0, 0);

      scene.add(plane);
    },
    // 创建方块和球
    createCubeAndSphere() {
      const geom = new THREE.BoxGeometry(4, 4, 4); // 创建几何对象geom
      const material = new THREE.MeshLambertMaterial({ color: 0xff0000 }); // 创建材质对象material
      let cube = new THREE.Mesh(geom, material); // 创建网格对象cube
      cube.castShadow = true;
      cube.position.set(-4, 3, 2);
      scene.add(cube); // 将网格对象添加到场景

      const sphereGeometry = new THREE.SphereGeometry(4, 20, 20); // 创建几何对象sphereGeometry
      const sphereMaterial = new THREE.MeshLambertMaterial({ color: 0x7777ff }); // 创建材质对象sphereMaterial
      let sphere = new THREE.Mesh(sphereGeometry, sphereMaterial); // 创建网格对象sphere
      sphere.castShadow = true;
      sphere.position.set(20, 5, 2);
      scene.add(sphere); // 将网格对象添加到场景
    },
    createLight() {
      // 添加聚光灯
      const spotLight = new THREE.SpotLight(0xfafafa);
      spotLight.position.set(-40, 80, -10);
      spotLight.castShadow = true;
      scene.add(spotLight); // 聚光灯添加到场景中

      // 环境光
      ambient = new THREE.AmbientLight(0x666666);
      scene.add(ambient);
    },
    createCamera() {
      const element = document.getElementById("scene");
      const width = element.clientWidth;
      const height = element.clientHeight;
      const k = width / height; //窗口宽高比
      camera = new THREE.PerspectiveCamera(45, k, 0.1, 1000);
      camera.position.set(-25, 30, 25);
      // 设置相机方向
      camera.lookAt(new THREE.Vector3(10, 0, 0));
      scene.add(camera);
    },
    // 创建渲染器
    createRender() {
      const element = document.getElementById("scene");
      renderer = new THREE.WebGLRenderer();
      // 设置渲染区域尺寸
      renderer.setSize(element.clientWidth, element.clientHeight);
      // 设置背景色
      renderer.setClearColor(0x3f3f3f, 1);
      element.appendChild(renderer.domElement);
    },
    UpdateAmbientLight() {
      ambient.color = new THREE.Color(this.ambientColor);
    },
    render() {
      this.UpdateAmbientLight();
      renderer.render(scene, camera);
      // 通过requestAnimationFrame实现周期性调用render
      requestAnimationFrame(this.render);
    },
    createControls() {
      controls = new OrbitControls(camera, renderer.domElement);
    },
  },
};
</script>

<style scoped lang="less">
.ambient-light {
  width: 100%;
  height: 100%;
  position: relative;
  .color-select {
    width: 100px;
    height: 100px;
    background-color: #fff;
    position: absolute;
    top: 10px;
    right: 10px;
    z-index: 100;
  }
}
#scene {
  width: 100%;
  height: 100%;
}
</style>
